package com.myeasyexcel.utils;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.IndexedColors;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class WebWriteExcel {

    /**
     * 动态下拉map key: 所在第几列 ，  value：动态下拉列表框
     */
    private Map<Integer, String[]> dropDownMap = new HashMap<>();

    /**
     * 联动列表的第一层
     */
    private List<String> strList = new ArrayList<>();

    /**
     * key：联动的第一层   value：对应的下级
     */
    private Map<String, List<String>> linkageMap = new HashMap<>();

    public WebWriteExcel(Map<Integer, String[]> dropDownMap) {
        this.dropDownMap = dropDownMap;
    }

    public WebWriteExcel(List<String> strList, Map<String, List<String>> linkageMap) {
        this.strList = strList;
        this.linkageMap = linkageMap;
    }

    public WebWriteExcel(Map<Integer, String[]> dropDownMap, List<String> strList, Map<String, List<String>> linkageMap) {
        this.dropDownMap = dropDownMap;
        this.strList = strList;
        this.linkageMap = linkageMap;
    }

    public WebWriteExcel() {
    }


    @SuppressWarnings("rawtypes")
    public void webWriteExcel(HttpServletResponse response, List<? extends ExcelErrMsg> errList,
                              Class clazz, String fileName, ExcelTypeEnum excelTypeEnum) throws IOException {
        try {
            webWriteExcel(response, errList, clazz, fileName, fileName, excelTypeEnum);
        } catch (Exception e) {
            log.error("导出文件错误", e);
        }
    }

    @SuppressWarnings("rawtypes")
    public static void webWriteExcel(HttpServletResponse response, List<? extends ExcelErrMsg> errList,
                                     Class clazz, String fileName, String sheetName, ExcelTypeEnum excelTypeEnum) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        try {
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''"
                    + URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20")
                    + excelTypeEnum.getValue());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 头的策略applicationResponse = {ResponseFacade@13592}
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为白
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            EasyExcelFactory.write(outputStream, clazz)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .registerWriteHandler(new StyleExcelHandler())
                    .registerWriteHandler(new DropDownSheetWriteHandler())
                    .relativeHeadRowIndex(1)
                    .sheet(sheetName).doWrite(errList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    @SuppressWarnings("rawtypes")
    public void webWriteExcelPlus(HttpServletResponse response, List<?> list,
                                  Class clazz, String fileName, String sheetName, ExcelTypeEnum excelTypeEnum) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        try {
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''"
                    + URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20")
                    + excelTypeEnum.getValue());
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            // 背景设置为白
            headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
            // 内容的策略
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
            ServletOutputStream outputStream = response.getOutputStream();
            try {
                EasyExcelFactory.write(outputStream, clazz)
                        .registerWriteHandler(new StyleExcelHandler())
                        .registerWriteHandler(new DropDownSheetWriteHandler())
                        .registerWriteHandler(new LinkageLevelHandler(strList, linkageMap))
                        .registerWriteHandler(horizontalCellStyleStrategy)
                        .registerWriteHandler(new InfiniteDropDownHandler(dropDownMap))
                        .relativeHeadRowIndex(1)
                        .sheet(sheetName).doWrite(list);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                outputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
